package dbrepository

import (
	_ "github.com/go-sql-driver/mysql"
	"database/sql"
	"fmt"
	"errors"
)
var(
	ErrDBOperationFail=errors.New("数据库操作失败！")
	ErrDBConnectFail=errors.New("数据库连接失败！")
	ErrDBSqlCommand=errors.New("数据库sql语法错误！")

)
// database repository
type DBRepository struct {
	*sql.DB
}

var MySqlDB *DBRepository

func init() {
	MySqlDB1, err := NewMySqlConnection(ConnectionString)
	if MySqlDB1 ==nil{
		fmt.Println("数据库初始化失败")
		return
	}
	MySqlDB1.SetMaxOpenConns(2000) //设置最大打开连接数据 0 不限
	MySqlDB1.SetMaxIdleConns(1000) //设置闲置连接数
	err = MySqlDB1.Ping()
	if err != nil {
		fmt.Println(err)
	}
	MySqlDB = MySqlDB1
	fmt.Println("连接数据库成功")
}

//consts connection string
const ConnectionString string = "denlery:abcd1234@tcp(192.168.1.229:3306)/AppCenter?charset=utf8"
//create mysql default connection
func NewMySqlDefaultConnection() (*DBRepository, error) {
	return NewConnection("mysql", ConnectionString)
}

//create mysql connection
func NewMySqlConnection(dataSourceName string) (*DBRepository, error) {
	return NewConnection("mysql", dataSourceName)
}

// create connection
func NewConnection(driverName string, dataSourceName string) (*DBRepository, error) {
	db, err := sql.Open(driverName, dataSourceName)
	if err != nil {
		fmt.Println(err)
		return nil, ErrDBConnectFail
	}
	DbRepository := &DBRepository{db}
	return DbRepository, nil
}

/*func (db *DBRepository) Prepare(sql string)(*sql.Stmt,error)  {
	stmt,err :=db.DB.Prepare(sql)
	if err!=nil{
		return nil,exception.ErrDBSqlCommand
	}
	return stmt,nil
}*/
func (db *DBRepository) Exec(query string,args ...interface{})(error)  {
	stmt, err := db.Prepare(query)
	defer stmt.Close()
	if err != nil {
		return errors.New("系统错误,数据库sql语法错误")
	}
	_,err = stmt.Exec(args...)
	if err !=nil{
		fmt.Println(err)
		return errors.New("系统错误,sql执行失败")
	}
	return nil
}
func (db *DBRepository) QueryRow(query string, callback func(isHasRows bool, row *sql.Rows) error, args ...interface{}) error {
	stmt, err := db.Prepare(query)
	defer stmt.Close()
	if err != nil {
		fmt.Println(err)
		return errors.New("系统错误,数据库sql语法错误！")
	}
	rows, err := stmt.Query(args...)
	defer rows.Close()
	if err != nil {
		fmt.Println(err)
		return errors.New("系统错误,数据执行失败！")
	}
	isHasRows := rows.Next()
	if rows.Err() != nil {
		fmt.Println(rows.Err())
		return errors.New("系统错误,数据获取失败！")
	}
	err = callback(isHasRows, rows)
	if err != nil {
		fmt.Println(err)
		return errors.New("系统错误,数据解析失败！")
	}

	return nil

}
// query count
func (db *DBRepository) QueryCount(query string, args ...interface{}) (int, error) {
	stmt, err := db.Prepare(query)
	defer stmt.Close()
	if err != nil {
		return 0, errors.New("系统错误,数据库sql语法错误！")
	}
	rows, err := stmt.Query(args...)
	defer rows.Close()
	if err != nil {
		fmt.Println(err)
		return 0, errors.New("系统错误,数据执行失败！")
	}
	count := 0
	if rows.Next() {
		if rows.Err() != nil {
			fmt.Println(rows.Err())
			return 0, errors.New("系统错误,数据获取失败！")
		}
		err = rows.Scan(&count)
		if err != nil {
			fmt.Println(err)
			return 0, errors.New("系统错误,数据解析失败！")
		}
	}

	return count, nil
}



